#pragma once

#include "ChunkItem.h"

#include "thread.h"

#include "Hull.h"

class TiXmlElement;
class TiXmlNode;

namespace ChunkSystem
{
	typedef std::pair< int16 , int16 > GridCoord; 

	class Portal;
	class ChunkBoundary;
	class ChunkData;
	class ChunkSpace;
	class Column;

	class Chunk
		: public ChunkItem
	{
	public:

		enum State
		{
			eUnload = 0,
			eLoading,
			eLoaded,
			eBinded
		};

		typedef std::vector< ChunkBoundary* > Boundaries;
		typedef Boundaries::iterator	ItrBounaries;
		typedef Boundaries::const_iterator	ItrConstBounaries;

		typedef std::vector< ChunkItem* > IncludeChildren;
		typedef IncludeChildren::iterator ItrIncludeChildren;

		typedef std::set< Column* >	ColumnSet;

		Chunk(const String& strChunkId, ChunkItem* pOwner, ChunkSpace* pOwnerSpace);
		virtual ~Chunk(void);

		virtual void UpdateAABB( void ){}

		bool GenerateBoudaries( TiXmlElement* pDataRoot );

		virtual bool Load( TiXmlElement* pChunkData );
		virtual void Unload( void );

		void AddChunkItem( ChunkItem* pChunkItem );
		IncludeChildren& GetIncludeChildren( void );

		State& GetCurState( void ) { return m_curState;}
		ChunkSpace* GetOwnerSpace( void ) const { return m_pOwnerSpace; }

		void Focus( void );
		void Ignore( void );
		
		void BindPorts( void );
		void Bind( void );
		void Bind( Chunk* pChunk );
		void Loose( void );

		//chunk item interface
		virtual void CreateVisible(IRenderableFactory* pFac);
		virtual void DestoryVisible(void);
		virtual void DrawVisible( IRenderer* pRenderer );

		const Boundaries& GetBoundaries( void ) const;
		HullTree::HullOutLines& GetHullOutLines( void );

	protected:

		typedef std::vector< TiXmlNode* > BoundariesData;
		typedef BoundariesData::iterator	ItrBoundariesData;

		virtual bool _LoadBoundaryInfo( TiXmlNode* pData , BoundariesData& rBoundriesData ) = 0;
		virtual bool _FormPortal( Chunk* pToChunk, Portal& oportal );
		
		bool _CanBind( Portal& portalA, Portal& portalB, Chunk* chunkA, Chunk* chunkB );

		//bool _AutomaticBind( Chunk* pChunk, Portal& oPortal );

	protected:

		State					m_curState;

		Boundaries				m_Boundaries; //for convex
		Boundaries				m_Joints;	//for linking

		IncludeChildren			m_includeChildren;

		ChunkSpace*				m_pOwnerSpace;

		static	float			m_fMaxHeight;
		static	float			m_fMinHeight;

		HullTree::HullOutLines	m_HullOutLines;
	};

	class ChunkFactory
		:public ChunkItemFactory
	{

	};
}